home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 05.zip / BS1 part 5 / SASC_6.0_Disk_7.adf / Source_And_Examples / extras / Memlib / memlib.doc < prev    next >
Encoding:
Text File  |  1992-07-30  |  13.6 KB  |  309 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
  2. * |_o_o|\\ Copyright (c) 1988-1992 Doug Walker                            *
  3. * |. o.| ||          All Rights Reserved.                                 *
  4. * | .  | ||          Written by Doug Walker                               *
  5. * | o  | ||          405 B3 Gooseneck Drive                               *
  6. * |  . |//           Cary, NC 27513                                       *
  7. * ======             bix: djwalker                                        *
  8. *                    usenet: walker@unx.sas.com                           *
  9. \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  10.  
  11. This material is Copyright (c) 1988-1992 by Doug Walker.
  12. It may be distributed freely as long as the following restrictions are met:
  13.  
  14.    1.  All files present in the distribution package must be redistributed
  15.        with the package, including this documentation file.  If you 
  16.        distribute on diskette, all files must be on a single diskette.
  17.  
  18.    2.  The distributor may charge a fee to recover distribution costs.
  19.        The fee for diskette distribution should not be more than the cost 
  20.        to obtain a diskette from the Fred Fish collection.
  21.  
  22.    3.  The distributor agrees to cease distributing the programs and data
  23.        involved if requested to do so by the author.
  24.  
  25. ------------------------------DISCLAIMER
  26.  
  27. Use this software at your own risk.  The author will not be liable for 
  28. any damage arising from the failure of this program to perform as described,
  29. or any destruction of other programs or data residing on a system 
  30. attempting to run the program.  While no damaging errors are known, the 
  31. user of this program uses it at his or her own risk.
  32.  
  33. ============================================================================
  34.  
  35. Welcome to the MemWatch Library!  The MemWatch library adds lots of memory 
  36. debugging features that you link into your program.  The library does what
  37. it can to validate your memory allocations and frees and to encourage any
  38. misuse of memory to result in a reproducable crash rather than an erratic
  39. bug.
  40.  
  41. The MemWatch library compiles under SAS/C 6.0 and above.  If the memory
  42. features are turned off, no additional code will be added to your 
  43. program.  If they are enabled, your code will call routines in the
  44. MemWatch library automatically instead of malloc, calloc, realloc, free,
  45. AllocMem and FreeMem.
  46.  
  47. The program-level memory debug routines are controlled by a 
  48. preprocessor symbol, MWDEBUG, and are #defined to nothing if the 
  49. symbol is not defined.  To link the program-level routines into 
  50. your code, do the following:
  51.  
  52. 1. Include the file "memwatch.h" into each file that will be
  53.    allocating or freeing memory.   (Don't include "mempriv.h" - it is
  54.    for the internal use of the memwatch.lib routines only).
  55.  
  56. 2. #define the symbol MWDEBUG to 1 at some point before memwatch.h 
  57.    is included.  The symbol must be defined in each compilation 
  58.    somewhere.  It could be done in an include file, in the
  59.    program file, or on the compiler command line.  If the symbol 
  60.    MWDEBUG is not defined or is defined to 0, all the  MemWatch 
  61.    routines disappear, thus adding nothing to your code size.
  62.  
  63. 3. Recompile all files in your program.
  64.  
  65. Unlike previous versions of MemLib, you do not need to add calls to
  66. the functions MWInit and MWTerm to make the MemWatch library work.
  67. MemWatch now takes advantage of SAS/C autoinitialization and
  68. autotermination functions to initialize and terminate the memory
  69. debugging.
  70.  
  71. The program-level MemWatch interface is described below.  Note that
  72. your code will probably not need to call any of these functions
  73. directly.
  74.  
  75. ---------------------------------------------------------------------
  76.  
  77.    void MWInit(BPTR debugfile, LONG flags, char *dbfilename);
  78.  
  79.    You are not required to call MWInit, but you may call it if
  80.    you want to change the way MemLib behaves after it has been
  81.    initialized.  If you do not call it explicitly, the autoinit
  82.    code calls it for you as described at the end of this section.
  83.  
  84.    The 'flags' parameter can be one or more of the following, ORed together 
  85.    if necessary:
  86.  
  87.    MWF_NOLOG:   If set, do not print error or warning messages.  Useful
  88.                 only if you want to turn off debugging for some reason.
  89.                 Saves some CPU time.
  90.  
  91.    MWF_CHECK:   If set, check all allocated memory each time a memory 
  92.                 routine is called.  Every AllocMem, FreeMem, malloc or 
  93.                 free call will cause all allocated memory to be examined.
  94.                 This can be extremely slow, but it's safe.
  95.  
  96.    MWF_NOFREE:  If set, do not free memory left allocated when the
  97.                 program exits.  If not set, any memory you allocated
  98.                 and did not free will be freed on your behalf.
  99.  
  100.    MWF_NOFTRASH: If set, freed memory will not be trashed.  This does
  101.                 save some time, but it is valuable to trash freed memory
  102.                 to verify you aren't still using it.
  103.  
  104.    MWF_NOFKEEP: If set, free memory immediately when FreeMem or free is
  105.                 called.  If not set, 'freed' memory will actually be kept
  106.                 on a chain and checked periodically for a change in its
  107.                 value.  If the value changes, you have written to freed
  108.                 memory.  MWF_NOFTRASH implies MWF_NOKEEP, since there is
  109.                 no point in keeping memory that you don't know the value 
  110.                 of.  If this flag is NOT set, kept memory will be freed 
  111.                 if the machine actually runs out of memory.
  112.  
  113.    MWF_NOATRASH: If set, memory will not be trashed upon allocation.  This
  114.                 also saves some time, but it is extremely valuable to trash
  115.                 allocated memory to be sure you aren't relying on side
  116.                 effects for your program to run correctly.
  117.  
  118.    MWF_SERIAL:  If you have recompiled MemWatch to use Commodore's debug.lib
  119.                 to put information to the serial port, this flag tells 
  120.                 memlib to use this feature.  If you have not recompiled
  121.                 to use debug.lib, this flag does nothing.
  122.  
  123.    If the MWF_SERIAL flag is not active, the other parameters are used to
  124.    determine where the debugging output goes as follows:
  125.  
  126.    If you specify the "debugfile" parameter, it should be the result
  127.    of a call to the AmigaDOS function Open().  The specified filehandle
  128.    will be used for all debugging messages.
  129.    
  130.    If "debugfile" is NULL but you specify a filename with the "dbfilename"
  131.    parameter, MemWatch will perform an Open() on the specified filename
  132.    WHEN AN ERROR OCCURS.  Close() will be called automatically the next
  133.    time you call MWInit() or MWTerm(), or when your program exits.
  134.  
  135.    If both "debugfile" and "dbfilename" are NULL, the AmigaDOS function
  136.    Output() is called and the result is used for the output.
  137.    
  138.    The intent is for you to provide "debugfile" if you have a convenient
  139.    place for debugging output to go already.  If you don't have a 
  140.    convenient place, you can pass the name of a console window as
  141.    "dbfilename" :
  142.  
  143.       MWInit(NULL, 0, "CON:0/0/639/199/MemLib output");
  144.  
  145.    The console window will be opened if/when something interesting 
  146.    happens, but will stay out of the way until then.  Finally, if your
  147.    program is run from the CLI or Shell, you can pass NULL for both
  148.    'debugfile' and 'dbfilename' and output will be sent to the Shell 
  149.    window.
  150.  
  151.    If you do not call MWInit() explicitly, it is called for you by the
  152.    autoinitialization routine.  The autoinitialization routine uses
  153.    the external integer variable __MWFlags as the "flags" parameter
  154.    and the external character pointer variable __MWLogName as the
  155.    "dbfilename" parameter.  You can declare these variables in your
  156.    code or allow them to be pulled in from the MemWatch library.  Their
  157.    default values as specified in the MemWatch library are:
  158.    
  159.       unsigned long __MWFlags = MWF_SERIAL;
  160.  
  161.       char *__MWLogName = "CON:0/0/639/199/MemLib";
  162.  
  163.    Note that even though the default __MWFlags value is MWF_SERIAL, the
  164.    serial port will not be used unless you edit mempriv.h to define
  165.    the symbol USEDEBUGLIB to 1.  See the "additional features" section
  166.    below for details.
  167.  
  168.    If the symbol MWDEBUG not defined to 1 or higher, MWInit() is defined
  169.    as an empty macro.
  170.  
  171. ---------------------------------------------------------------------
  172.  
  173.  
  174.    void MWTerm(void);
  175.  
  176.    You are not required to call this routine.  If you do call it, 
  177.    however, the log file is closed and all memory routines are
  178.    disabled.  Any calls to allocate memory after MWTerm() has been
  179.    called will fail!
  180.  
  181.    MWTerm() will always generate a check of all memory allocated
  182.    through the MemWatch library.
  183.  
  184.    If the symbol MWDEBUG is not defined to 1 or higher, MWTerm() is defined
  185.    as an empty macro.
  186.  
  187. ---------------------------------------------------------------------
  188.  
  189.    char *MWAllocMem(LONG size, LONG flags, char *file, int line);
  190.  
  191.    You should not call this routine directly, but your AllocMem, malloc
  192.    and realloc calls will be defined to call it if the symbol MWDEBUG 
  193.    is defined to 1.
  194.  
  195. ---------------------------------------------------------------------
  196.  
  197.    void MWFreeMem(char *ptr, LONG size, char *file, int line);
  198.  
  199.    You should not call these routine directly, but your FreeMem
  200.    and free calls will be defined to call them if the symbol 
  201.    MWDEBUG is defined.
  202.  
  203. ---------------------------------------------------------------------
  204.  
  205.    void MWReport(FILE *reportfile, char *title, int level);
  206.  
  207.    Call this routine any time you want a report on how much memory
  208.    you are using.  The 'reportfile' is a file to send the report
  209.    to.  If reportfile is NULL, the debug log file will be used.
  210.  
  211.    MWReport() always forces a MWCheck() call.
  212.  
  213.    'title' is any character string you want.  It will be used to
  214.    label the dumped output.  Use NULL for no title.
  215.  
  216.    'level' tells how much detail you want in the report.  It is one
  217.    of the following values:
  218.  
  219.    MWR_NONE - Don't print anything.
  220.    MWR_SUM  - Print current and total memory usage
  221.    MWR_FULL - Print a short description of each outstanding allocation
  222.  
  223.    If the symbol MWDEBUG is not defined to 1 or higher, MWReport() is defined
  224.    as an empty macro.
  225.  
  226. ---------------------------------------------------------------------
  227.  
  228.    void MWCheck(void);
  229.  
  230.    Call this routine when you want to verify all your allocations are
  231.    clean.  If you have set the MWF_CHECK flag, all allocations
  232.    are checked every time you do an Alloc or Free operation anyway,
  233.    but you might want to use this directly if you do not set the flag 
  234.    or if you go long periods of time without allocating memory.
  235.  
  236.    If the symbol MWDEBUG is not defined to 1 or higher, MWCheck() is defined
  237.    as an empty macro.
  238.  
  239. ---------------------------------------------------------------------
  240.  
  241.    void MWLimit(LONG chip, LONG fast);
  242.  
  243.    Call this routine if you want to set an artificial 'cap' on the
  244.    amount of memory available.  Any allocations that ask for memory
  245.    that would push your total allocation above the specified limits
  246.    will fail, even if memory is available to fill them.  Keep in mind
  247.    that this doesn't take fragmentation into account, so it doesn't
  248.    guarantee your program will work on a smaller memory machine!
  249.    You can simulate out-of-memory conditions by calling MWLimit
  250.    with (0,0) - no allocations will ever succeed until the limit
  251.    is raised above the current usage level.
  252.  
  253.    The 'chip' parameter sets a limit on chip memory;  the 'fast'
  254.    parameter sets a limit on fast memory.  If the specified limit for
  255.    a category is -1, the limit will be set at the current usage amount.
  256.    Thus, any frees you do will improve your situation.
  257.  
  258.    If you want to remove a limit, set it to some extremely large value,
  259.    like 0x7fffffff.
  260.  
  261.    If the symbol MWDEBUG is not defined to 1 or higher, MWLimit() is defined
  262.    as an empty macro.
  263.  
  264.  
  265. ---------------------------------------------------------------------
  266.  
  267. ADDITIONAL FEATURES
  268.  
  269. Although you can set many of memlib's options from the MWInit call,
  270. there are some that can only be set by rebuilding the library itself.
  271. You can control these features by changing some #defines in the
  272. file "mempriv.h".
  273.  
  274. The define USEDEBUGLIB controls whether MemWatch.lib will use Commodore's
  275. debug.lib to put data to the serial port instead of a file handle.  Change
  276. the definition to 1 or higher to enable this feature, then link with
  277. Commodore's debug.lib or ddebug.lib.  If USEDEBUGLIB is on, output will
  278. go to the serial port (if you link with debug.lib) or the parallel port
  279. (if you link with ddebug.lib) unless you change your preference by
  280. calling MWInit.
  281.  
  282. The define MW_HEADLEN controls how many bytes will be set aside before your
  283. allocation to act as a header.  4 is the minimum, and the default.  The
  284. header will be checked for trashing when MWCheck() is called.
  285.  
  286. The define MW_HEADSTR sets the value that header memory will be set to.  It
  287. must be a string at least MW_HEADLEN bytes long.
  288.  
  289. The define MW_TRAILLEN controls how many bytes will be set aside after your
  290. allocation to act as a trailer.  16 is the default;  any value can be chosen
  291. for a maximum, but the higher the number, the more memory is wasted each time
  292. you call AllocMem!  The trailer will be checked whenever MWCheck() is called.
  293.  
  294. The define MW_TRAILSTR sets the value that trailer memory will be set to.  It
  295. must be at a string least MW_TRAILLEN bytes long.
  296.  
  297. The define MWATRASH sets the value that newly-allocated memory will be set to.
  298. The default is 0xaa.
  299.  
  300. The define MWFTRASH sets the value that newly-freed memory will be set to.
  301. The default is 0x55.
  302.  
  303. -----------------------------------
  304.  
  305. The enclosed program "example" shows how the MemWatch library can find
  306. problems in your code.  See the "READ.ME" file for details.
  307.  
  308.  
  309.